/* Copyright (C) 2011 The University of Michigan This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Please send inquiries to powertutor@umich.edu */ package vn.cybersoft.obs.andriod.batterystats2.components; import android.content.Context; import android.media.AudioManager; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.TreeSet; import vn.cybersoft.obs.andriod.batterystats2.PowerNotifications; import vn.cybersoft.obs.andriod.batterystats2.service.IterationData; import vn.cybersoft.obs.andriod.batterystats2.service.PowerData; import vn.cybersoft.obs.andriod.batterystats2.util.NotificationService; import vn.cybersoft.obs.andriod.batterystats2.util.Recycler; /** This class aims to log the audio device status once per log interval */ public class Audio extends PowerComponent { /** This class is the logger data file corresponding to Audio */ public static class AudioData extends PowerData { private static Recycler<AudioData> recycler = new Recycler<AudioData>(); public static AudioData obtain() { AudioData result = recycler.obtain(); if (result != null) return result; return new AudioData(); } @Override public void recycle() { recycler.recycle(this); } public boolean musicOn; private AudioData() { } public void init(boolean musicOn) { this.musicOn = musicOn; } public void writeLogDataInfo(OutputStreamWriter out) throws IOException { out.write("Audio-on " + musicOn + "\n"); } } private static class MediaData implements Comparable<Object> { private static Recycler<MediaData> recycler = new Recycler<MediaData>(); public static MediaData obtain() { MediaData result = recycler.obtain(); if (result != null) return result; return new MediaData(); } public void recycle() { recycler.recycle(this); } public int uid; public int id; public int assignUid; public int compareTo(Object obj) { MediaData x = (MediaData) obj; if (uid < x.uid) return -1; if (uid > x.uid) return 1; if (id < x.id) return -1; if (id > x.id) return 1; return 0; } public boolean equals(Object obj) { MediaData x = (MediaData) obj; return uid == x.uid && id == x.id; } } private AudioManager audioManager; private PowerNotifications audioNotif; private TreeSet<MediaData> uidData; public Audio(Context context) { if (NotificationService.available()) { uidData = new TreeSet<MediaData>(); audioNotif = new NotificationService.DefaultReceiver() { private int sysUid = -1; @Override public void noteSystemMediaCall(int uid) { sysUid = uid; } @Override public void noteStartMedia(int uid, int id) { MediaData data = MediaData.obtain(); data.uid = uid; data.id = id; if (uid == 1000 && sysUid != -1) { data.assignUid = sysUid; sysUid = -1; } else { data.assignUid = uid; } synchronized (uidData) { if (!uidData.add(data)) { data.recycle(); } } } @Override public void noteStopMedia(int uid, int id) { MediaData data = MediaData.obtain(); data.uid = uid; data.id = id; synchronized (uidData) { uidData.remove(data); } data.recycle(); } }; NotificationService.addHook(audioNotif); } audioManager = (AudioManager) context .getSystemService(Context.AUDIO_SERVICE); } @Override protected void onExit() { if (audioNotif != null) { NotificationService.removeHook(audioNotif); } } @Override public IterationData calculateIteration(long iteration) { IterationData result = IterationData.obtain(); AudioData data = AudioData.obtain(); data.init(uidData != null && !uidData.isEmpty() || audioManager.isMusicActive()); result.setPowerData(data); if (uidData != null) synchronized (uidData) { int last_uid = -1; for (MediaData dat : uidData) { if (dat.uid != last_uid) { AudioData audioPower = AudioData.obtain(); audioPower.init(true); result.addUidPowerData(dat.assignUid, audioPower); } last_uid = dat.uid; } } return result; } @Override public boolean hasUidInformation() { return audioNotif != null; } @Override public String getComponentName() { return "Audio"; } }